<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 手写 Promise 实现
    class MyPromise {
      static PENDING = 'pending';
      static FULFILLED = 'fulfilled';
      static REJECTED = 'rejected';

      constructor(executor) {
        this.status = MyPromise.PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];

        try {
          executor(this.resolve.bind(this), this.reject.bind(this));
        } catch (error) {
          this.reject(error);
        }
      }

      resolve(value) {
        if (this.status === MyPromise.PENDING) {
          this.status = MyPromise.FULFILLED;
          this.value = value;
          this.onFulfilledCallbacks.forEach(fn => fn());
        }
      }

      reject(reason) {
        if (this.status === MyPromise.PENDING) {
          this.status = MyPromise.REJECTED;
          this.reason = reason;
          this.onRejectedCallbacks.forEach(fn => fn());
        }
      }

      then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

        const promise2 = new MyPromise((resolve, reject) => {
          if (this.status === MyPromise.FULFILLED) {
            setTimeout(() => {
              try {
                const x = onFulfilled(this.value);
                resolve(x);
              } catch (error) {
                reject(error);
              }
            });
          }

          if (this.status === MyPromise.REJECTED) {
            setTimeout(() => {
              try {
                const x = onRejected(this.reason);
                resolve(x);
              } catch (error) {
                reject(error);
              }
            });
          }

          if (this.status === MyPromise.PENDING) {
            this.onFulfilledCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const x = onFulfilled(this.value);
                  resolve(x);
                } catch (error) {
                  reject(error);
                }
              });
            });

            this.onRejectedCallbacks.push(() => {
              setTimeout(() => {
                try {
                  const x = onRejected(this.reason);
                  resolve(x);
                } catch (error) {
                  reject(error);
                }
              });
            });
          }
        });

        return promise2;
      }
    }

    // 测试用例
    console.log('测试开始');

    // 测试成功的情况
    new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve('成功');
      }, 1000);
    }).then(
      value => { console.log('success:', value) },
      reason => { console.log('error:', reason) }
    );

    // 测试失败的情况
    new MyPromise((resolve, reject) => {
      setTimeout(() => {
        reject('失败');
      }, 2000);
    }).then(
      value => { console.log('success:', value) },
      reason => { console.log('error:', reason) }
    );

    // 测试链式调用
    new MyPromise((resolve, reject) => {
      resolve(1);
    })
      .then(value => {
        console.log('第一个then:', value);
        return value + 1;
      })
      .then(value => {
        console.log('第二个then:', value);
      });
  </script>
</body>

</html>